/**
	@author Maciej Suminski
	@version 1.0

	Projekt VoD-ka.
	Klasa obslugujaca protokol RTSP i dekodujaca MPEG. Zastosowano biblioteke FFmpeg <http://ffmpeg.org>.
*/

#include "player.hpp"

/**
    @brief Konstruktor podstawowy. Wymaga podania okna wxWidgets z ktorm bedzie wspolpracowal.
            Okno bedzie mialo ustawiane odpowiedni status (SetStatusText), a w przypadku
            odtwarzania - bedzie odswiezane (wydarzenie onPaint).
    @param wind  Okno na ktorym beda rysowane zdekodowane ramki.
*/
Player::Player(wxFrame* wind) {
    window = wind;
    state = STOP;
}

/**
    @brief Funkcja laczy sie z podanym adresem RTSP.
    @param address  Adres RTSP w postaci "rtsp://host.domena:port/strumien"
*/
void Player::open(string address) {
    try {
        window->SetStatusText(wxT("Łączenie..."));
        video = boost::shared_ptr<Video>(new Video(address));
        window->SetStatusText(wxString(string("Odtwarzanie " + address).c_str(), wxConvUTF8));
    }
    catch(string &str) {
        window->SetStatusText(wxString(str.c_str(), wxConvUTF8), 0);    // Wyswietlenie bledu
    }
}

/**
    @brief Funkcja uruchamia proces odtwarzania.
        W nowym watku uruchamiana jest petla odswiezajaca okno. Wymagane jest zaimplementowanie
        zdarzenia onPaint, gdzie beda rysowane ramki pobrane metoda getFrame.
*/
void Player::play()
{
    if(video) {
        state = PLAY;
        thread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&Player::thread_function, this)));
    }
}

/**
    @brief Zatrzymanie odtwarzanego nagrania.
*/
void Player::pause() {
    if(state == PLAY) state = PAUSE;
}

/**
    @brief Zwraca kolejna zdekodowana ramke wideo jako obiekt wxBitmap.
        Aby odtworzyc cale nagranie, nalezy wywolywac ta funkcje w metodzie obslugujacej
        wydarzenie onPaint okna wxWidgets.
    @return Kolejna zdekodowana ramka strumienia wideo.
*/
wxBitmap Player::getFrame() {
    try {
        return video->getFrame();
    }
    catch(string& str) {
        window->SetStatusText(wxString(str.c_str(), wxConvUTF8), 0);    // Wyswietlenie bledu
        state = Player::STOP;
        return wxBitmap();
    }
}

/**
    @brief Zwraca szerokosc ramki odtwarzanego strumienia wideo.
    @return 0 w przypadku bledu odtwarzania, w przeciwnym wypadku - szerokosc ramki odtwarzanego strumienia w pikselach.
*/
unsigned int Player::getWidth() {
    if(video) {
        return video->getWidth();
    }
    return 0;
}

/**
    @brief Zwraca wysokosc ramki odtwarzanego strumienia wideo.
    @return 0 w przypadku bledu odtwarzania, w przeciwnym wypadku - szerokosc ramki odtwarzanego strumienia w pikselach.
*/
unsigned int Player::getHeight() {
    if(video) {
        return video->getHeight();
    }
    return 0;
}

/**
    @brief Zwraca stan odtwarzacza.
    @return Wartosc PLAY, STOP lub PAUSE.
*/
volatile Player::State Player::getState() {
    return state;
}

/**
    @brief Watek wywolywany do odswiezania okna wxWidgets odtwarzajacego strumien wideo.
*/
void Player::thread_function() {
	while(state != STOP) {
	    if(state == PLAY) {
            window->Refresh();              // Odrysowanie okna (wtedy okno pobierze nowa ramke)
            boost::this_thread::sleep(boost::posix_time::milliseconds(45)); // Wymagane przerwanie, aby mozna bylo obsluzyc zadania uzytkownika
	    }
	}
}
